#!/bin/sh
#(c) Copyright Barry Kauler 2010, bkhome.org
#2010 Lesser GPL licence v2 (file:///usr/share/doc/legal/lgpl-2.1.txt)
#/etc/simple_network_setup/connections is created by SNS, /usr/local/simple_network_setup/sns
#100308 first version of script, open and wep networks only.
#100309 supports wpa. "version 1" released.
#100314 support ndiswrapper.
#100320 fix if essid has spaces. Add DHCPCDFIX parameter.
#100325 added 'stop' commandline option. added DHCPCDFIX for wired.
#100513 more delay, repeat scan attempt.
#100703 fix disconnect/reconnect.
#100804 while testing for module loaded, also test for valid macaddress.
#101122 wait for module to load.
#101216 more logging, to /tmp/simple_network_setup.
#110203 improve scanning.
#120204 BK: internationalized.
#121117 rerwin: Add dropwait option to dhcpcd startup.
#130411 skip dhcpcd if in frisbee mode

export TEXTDOMAIN=sns___rc.network
export OUTPUT_CHARSET=UTF-8
LANGORIG=$LANG

#each line of /etc/simple_network_setup/connections has everything known about a connection:
#(please ignore spaces, put here for readability only)
#Wireless:
#        1         2          3         4       5                                   6                 7           8                 9            10           11                 12         13                         14       15         16          17
#format: INTERFACE|IF_INTTYPE|IF_DRIVER|IF_BUS |IF_INFO                            |MACADDRESS       |CELL_NUMBER|CELL_ADDRESS     |CELL_CHANNEL|CELL_QUALITY|CELL_ENCRYPTIONKEY|CELL_ESSID|SEC_KEY                   |SEC_MGMT|ENCODEPROTO|WPA_DRIVER|DHCPCDFIX|
#ex:     wlan1    |Wireless  |rt73usb  |usb    |Ralink RT73 USB Wireless LAN driver|00:26:19:F5:AC:3D|01         |00:17:3F:68:33:7E|11          |70/70       |off               |belkin54g |000102030405060708090a0b0c|WEP     |           |wext      |         |
#Wired:
#        1         2          3         4       5                                       6                 7
#format: INTERFACE|IF_INTTYPE|IF_DRIVER|IF_BUS |IF_INFO                                |MACADDRESS       |DHCPCDFIX|
#ex:     eth0     |Wired     |sky2     |pci    |Marvell Yukon 2 Gigabit Ethernet driver|00:17:36:84:E5:1A|         |

#IMPORTANT: the INTERFACE field may be different at boot time, due to different plugged in network devices.

export LANG='C'
[ ! -s /etc/simple_network_setup/connections ] && exit
rm -f /tmp/sns_rc.network_exit 2>/dev/null #100703

if [ $1 ];then #100325
 case $1 in
  stop)
   if [ -f /tmp/sns_interface_success ];then
    INTERFACE="`cat /tmp/sns_interface_success`"
    rm -f /tmp/sns_interface_success
    [ "`pidof wpa_supplicant`" != "" ] && wpa_cli terminate #kill wpa_supplicant.
    ifconfig $INTERFACE down
    [ "`iwconfig $INTERFACE | grep "$INTERFACE" | grep "ESSID"`" != "" ] && iwconfig $INTERFACE essid off
    dhcpcd --release $INTERFACE 2>/dev/null
    ip route flush dev $INTERFACE #100703
    #in situation bring down interface from desktop icon...
    [ "$DISPLAY" ] && LANG=$LANGORIG yaf-splash -placement bottom -bg pink -timeout 5 -text "$(gettext 'Network interface') ${INTERFACE} $(gettext 'has been disabled')" &
   fi
   exit
  ;;
 esac
fi
rm -f /tmp/sns_interface_success 2>/dev/null

[ "`grep '|ndiswrapper|' /etc/simple_network_setup/connections`" != "" ] && modprobe ndiswrapper #100314

#wait for interfaces to become available...
#note, do not test for wlan0 or wlan1 (etc) to become available, as these can change depending on plugged-in devices.
WAITCNT=0 ; TESTLIST='|'
sleep 1
echo -n "" > /tmp/sns_connections_available
for ONEMODULE in `cut -f 3 -d '|' /etc/simple_network_setup/connections | sort -u | tr '\n' ' '` #100804
do
 TESTLIST="${TESTLIST}${ONEMODULE}|" #101122
 oPATTERN='^'"$ONEMODULE"'$'
 mPATTERN='|'"$ONEMODULE"'|'
 while [ 1 ];do #101122 wait for module to load.
  [ "`lsmod  | grep -v '^Module' | cut -f 1 -d ' ' | grep "$oPATTERN"`" != "" ] && break
  [ "`echo "$TESTLIST" | grep "$mPATTERN"`" != "" ] && continue 2 #avoid re-waiting on same module
  sleep 1
  WAITCNT=$(($WAITCNT + 1))
  [ $WAITCNT -gt 8 ] && continue 2 #no module loaded.
 done
 MACADDRESSES="`grep "$mPATTERN" /etc/simple_network_setup/connections | cut -f 6 -d '|' | sort -u | tr '\n' ' '`" #100804
 for MACADDRESS in $MACADDRESSES #100804
 do
  while [ 1 ];do
   ALL_MACADDRESS="`ifconfig -a | grep 'Link encap:Ethernet' | grep -o 'HWaddr .*' | cut -f 2 -d ' '`"
   if [ "`echo "$ALL_MACADDRESS" | grep "$MACADDRESS"`" != "" ];then
    #interface is ready. copy all connections with that module and macaddress...
    macPATTERN='|'"$MACADDRESS"'|'
    MACMATCH="`grep "$mPATTERN" /etc/simple_network_setup/connections | grep "$macPATTERN"`"
    [ "$MACMATCH" ] && echo "$MACMATCH" >> /tmp/sns_connections_available
    break
   fi
   WAITCNT=`expr $WAITCNT + 1`
   [ $WAITCNT -gt 12 ] && break 2 #timeout.
   sleep 1
  done
 done
done

[ ! -s /tmp/sns_connections_available ] && exit
INTERFACES="`ifconfig -a | grep -F 'Link encap:Ethernet' | cut -f1 -d' ' | tr '\n' ' '`"

##########WIRELESS##########
#121117 form dropwait argument for dhcpcd...
DROPWAIT="$(dhcpcd_dropwait_option)"
echo -n "" > /tmp/simple_network_setup/rc_network_wireless_connection_log
grep '|Wireless|' /tmp/sns_connections_available > /tmp/sns_connections_wireless
for INTERFACE in $INTERFACES #exs: wlan0 eth0
do
 [ ! -d /sys/class/net/${INTERFACE}/wireless ] && continue #only want wireless.
 echo -e "\n ${INTERFACE}" >> /tmp/simple_network_setup/rc_network_wireless_connection_log
 ifconfig $INTERFACE up
 [ $? -ne 0 ] && continue
 echo " SUCCESS: ifconfig ${INTERFACE} up" >> /tmp/simple_network_setup/rc_network_wireless_connection_log
 sleep 2 #100513
 SCANRESULT="`iwlist $INTERFACE scan`" ###SCANNING### 110203
 echo " EXECUTING SCAN: iwlist ${INTERFACE} scan | grep -v 'Scan completed'" >> /tmp/simple_network_setup/rc_network_wireless_connection_log
 echo " SCANRESULT=${SCANRESULT}" >> /tmp/simple_network_setup/rc_network_wireless_connection_log
 #note, possible to get: 'wlan0     No scan results' so delay then try again...
 if [ "`echo "$SCANRESULT" | grep 'Scan completed'`" = "" ];then #100513 110203
  sleep 2
  SCANRESULT="`iwlist $INTERFACE scan`" ###SCANNING###
  echo " EXECUTING SCAN AGAIN: iwlist ${INTERFACE} scan | grep -v 'Scan completed'" >> /tmp/simple_network_setup/rc_network_wireless_connection_log
  echo " SCANRESULT=${SCANRESULT}" >> /tmp/simple_network_setup/rc_network_wireless_connection_log
 fi
 ifconfig $INTERFACE down
 echo " EXECUTING: ifconfig $INTERFACE down" >> /tmp/simple_network_setup/rc_network_wireless_connection_log #110203
 if [ "`echo "$SCANRESULT" | grep 'Scan completed'`" = "" ];then #110203
  echo 'SCAN FAILURE, EXPECTED STRING "Scan completed"' >> /tmp/simple_network_setup/rc_network_wireless_connection_log
  continue #110203
 fi
 #convert each found network into a single line... 110203
 SRLINES="`echo "$SCANRESULT" | grep -v 'Scan completed' | tr '|' ' ' | tr '\n' '|' | sed -e 's%       Cell %\n%g' | tr -s ' '`"
 echo "$SRLINES" |
 while read ONELINE
 do
  [ "$ONELINE" = "" ] && continue
  [ "$ONELINE" = " " ] && continue
  CELL_ESSID="`echo -n "$ONELINE" | grep -o ' ESSID:.*' | cut -f 2 -d '"'`" #'geany
  essidPATTERN='|'"$CELL_ESSID"'|'
  CONNECTDATA="`grep "$essidPATTERN" /tmp/sns_connections_wireless`"
  if [ "$CONNECTDATA" != "" ];then
   MACADDRESS="`ifconfig -a $INTERFACE | grep -o 'HWaddr .*' | cut -f 2 -d ' '`"
   maPATTERN='|'"$MACADDRESS"'|'
   CONNECTDATA="`echo "$CONNECTDATA" | grep "$maPATTERN"`"
   echo "   MACADDRESS=$MACADDRESS CONNECTDATA=$CONNECTDATA" >> /tmp/simple_network_setup/rc_network_wireless_connection_log
   if [ "$CONNECTDATA" != "" ];then
    #note, INTERFACE not necessarily the same as in first field of CONNECTDATA.
    CELL_CHANNEL="`echo -n "$CONNECTDATA" | cut -f9 -d'|'`"
    CELL_ENCRYPTIONKEY="`echo -n "$CONNECTDATA" | cut -f11 -d'|'`"
    SEC_KEY="`echo -n "$CONNECTDATA" | cut -f13 -d'|'`" #ex: thebigbaddog
    SEC_MGMT="`echo -n "$CONNECTDATA" | cut -f14 -d'|'`" #exs: WEP, WPA-PSK
    ENCODEPROTO="`echo -n "$CONNECTDATA" | cut -f15 -d'|'`" #exs: WEP: restricted, open. WPA*: AES, TKIP.
    WPA_DRIVER="`echo -n "$CONNECTDATA" | cut -f16 -d'|'`" #ex: wext
    DHCPCDFIX="`echo -n "$CONNECTDATA" | cut -f17 -d'|'`" #100320 ex: -I ''
    iwconfig $INTERFACE mode managed
    echo "    RESULT=$? FOR: iwconfig $INTERFACE mode managed" >> /tmp/simple_network_setup/rc_network_wireless_connection_log
    iwconfig $INTERFACE channel $CELL_CHANNEL
    echo "    RESULT=$? FOR: iwconfig $INTERFACE channel $CELL_CHANNEL" >> /tmp/simple_network_setup/rc_network_wireless_connection_log
    iwconfig $INTERFACE essid "$CELL_ESSID"
    echo "    RESULT=$? FOR: iwconfig $INTERFACE essid \"$CELL_ESSID\"" >> /tmp/simple_network_setup/rc_network_wireless_connection_log
    RUNWPASUPP='no'
    if [ "$CELL_ENCRYPTIONKEY" == "on" ];then
     case $SEC_MGMT in
      WEP)  iwconfig $INTERFACE key $ENCODEPROTO $SEC_KEY ;; #ex: iwconfig wlan0 key open 00112233445566778899aabbcc
      WPA*) RUNWPASUPP='yes' ;;
     esac
    fi
    MODTIME1="`stat --format=%Y /etc/resolv.conf`"
    ifconfig $INTERFACE up #hmmm, it seems need to bring up after all the iwconfig operations!
    if [ $? -eq 0 ];then
     echo "     RESULT=$? FOR: ifconfig $INTERFACE up" >> /tmp/simple_network_setup/rc_network_wireless_connection_log
     wCNT=0
     if [ "$RUNWPASUPP" = "yes" ];then
      if [ -f "/etc/simple_network_setup/wpa_supplicant.conf-${CELL_ESSID}-${MACADDRESS}" ];then
       wpa_supplicant -B -D${WPA_DRIVER} -i${INTERFACE} -c"/etc/simple_network_setup/wpa_supplicant.conf-${CELL_ESSID}-${MACADDRESS}"
       echo "       RESULT=$? FOR: wpa_supplicant -B -D${WPA_DRIVER} -i${INTERFACE} -c\"/etc/simple_network_setup/wpa_supplicant.conf-${CELL_ESSID}-${MACADDRESS}\"" >> /tmp/simple_network_setup/rc_network_wireless_connection_log
       while [ $wCNT -le 20 ];do #100314 wait until wpa_supplicant has "connected".
        sleep 1
        echo "        TEST: wpa_cli -i $INTERFACE status" >> /tmp/simple_network_setup/rc_network_wireless_connection_log
        wpa_cli -i $INTERFACE status >> /tmp/simple_network_setup/rc_network_wireless_connection_log
        echo "        RESULT=$? wCNT=$wCNT" >> /tmp/simple_network_setup/rc_network_wireless_connection_log
        [ "`wpa_cli -i $INTERFACE status | grep '^bssid=[0-9a-f]'`" != "" ] && break
        #[ "`wpa_cli -i $INTERFACE status | grep 'COMPLETED'`" != "" ] && break
        wCNT=$(($wCNT + 1))
       done
      fi
     fi
     grep -q -s '^frisbee_mode=1' /etc/frisbee/frisbee.conf && continue #130411
     [ $wCNT -le 20 ] && dhcpcd $DHCPCDFIX $DROPWAIT $INTERFACE #100320 121115
    fi
    MODTIME2="`stat --format=%Y /etc/resolv.conf`"
    [ "`grep -v '^#' /etc/resolv.conf`" == "" ] && MODTIME2=$MODTIME1 #fail.
    if [ "$MODTIME2" != "$MODTIME1" ];then
     echo "     SUCCESS" >> /tmp/simple_network_setup/rc_network_wireless_connection_log
     #in situation bring up interface from desktop icon...
     [ "$DISPLAY" ] &&  yaf-splash -placement bottom -bg green -timeout 5 -text "Network interface ${INTERFACE} has been activated" &
     echo "$INTERFACE" > /tmp/sns_interface_success #100325
     #break
     touch /tmp/sns_rc.network_exit #'exit' only terminates this code block (which is running as a separate process).
     exit #one internet connection is enough!
    else
     echo "     FAIL" >> /tmp/simple_network_setup/rc_network_wireless_connection_log
     [ "`pidof wpa_supplicant`" != "" ] && wpa_cli terminate #kill wpa_supplicant.
     ifconfig $INTERFACE down
     [ "`iwconfig $INTERFACE | grep "$INTERFACE" | grep "ESSID"`" != "" ] && iwconfig $INTERFACE essid off
     dhcpcd --release $INTERFACE 2>/dev/null
     ip route flush dev $INTERFACE #100703
    fi 
   fi
  fi
 done
 [ -f /tmp/sns_rc.network_exit ] && break #100320 bug fix, if more than one wireless interface.
done

[ -f /tmp/sns_rc.network_exit ] && exit

##########WIRED##########
grep '|Wired|' /tmp/sns_connections_available > /tmp/sns_connections_wired
for INTERFACE in $INTERFACES #exs: wlan0 eth0
do
 [ -d /sys/class/net/${INTERFACE}/wireless ] && continue #only want wired.

 ifconfig $INTERFACE up > /tmp/sns_wired_log 2>&1
 [ $? -ne 0 ] && continue

 if ! ifplugstatus-0.18 "$INTERFACE" | grep -F -q 'link beat detected' ;then
  sleep 1
  if ! ifplugstatus "$INTERFACE" | grep -F -q 'link beat detected' ;then
   sleep 1
   if ! ifplugstatus-0.18 "$INTERFACE" | grep -F -q 'link beat detected' ;then
    sleep 1
    if ! ifplugstatus "$INTERFACE" | grep -F -q 'link beat detected' ;then
     sleep 1
     if ! ethtool "$INTERFACE" | grep -Fq 'Link detected: yes' ; then
      ifconfig $INTERFACE down
      continue #no network.
     fi
    fi
   fi
  fi
 fi

 grep -q -s '^frisbee_mode=1' /etc/frisbee/frisbee.conf && continue #130411
 MACADDRESS="`ifconfig -a $INTERFACE | grep -o 'HWaddr .*' | cut -f 2 -d ' '`"
 maPATTERN='|'"$MACADDRESS"'|'
 DHCPCDFIX="`grep "$maPATTERN" /tmp/sns_connections_wired | head -n 1 | cut -f 7 -d '|'`" #100325 ex: -I ''

 MODTIME1="`stat --format=%Y /etc/resolv.conf`"
 dhcpcd $DHCPCDFIX $INTERFACE >> /tmp/sns_wired_log 2>&1
 MODTIME2="`stat --format=%Y /etc/resolv.conf`"
 [ "`grep -v '^#' /etc/resolv.conf`" == "" ] && MODTIME2=$MODTIME1 #fail.

 if [ "$MODTIME2" != "$MODTIME1" ];then
  echo "$INTERFACE" > /tmp/sns_interface_success #100325
  exit #success.
 else
  ifconfig $INTERFACE down
  dhcpcd --release $INTERFACE 2>/dev/null
  ip route flush dev $INTERFACE #100703
 fi
 
done


###END###
